package com.rocky.component.util;

import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Set;

/**
 * @author rocky
 * date 2025-07-28
 * Description:
 */
public class ObjectMapperUtil {

    private static final String DYNAMIC_FILTER_NAME = "dynamicFilter";

    private static final ObjectMapper objectMapper = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .registerModule(new JavaTimeModule().addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))));

    @JsonFilter(DYNAMIC_FILTER_NAME)
    private interface DynamicFilter {
    }

    public static ObjectMapper get() {
        return objectMapper;
    }

    public static String jsonString(Object object) {
        try {
            return objectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public static String jsonString(Object object, Set<String> excludeProperty) {
        if (CollectionUtils.isEmpty(excludeProperty)) {
            return jsonString(object);
        }

        SimpleFilterProvider simpleFilterProvider = new SimpleFilterProvider().addFilter(DYNAMIC_FILTER_NAME, SimpleBeanPropertyFilter.serializeAllExcept(excludeProperty));
        ObjectMapper tempObjectMapper = objectMapper
                .copy()
                .addMixIn(object.getClass(), DynamicFilter.class)
                .setFilterProvider(simpleFilterProvider);

        try {
            return tempObjectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }
}